// /////////////////////////////////////////////////////////////////////////////
//
// Name:            asSerializable.h
// Author:          Michael Bartsch (ZCCdark203)
//
// Desc :           Binds the Serializable class to AngelScript
//
// License:         Copyright (C) 2009 Michael Bartsch and Contributors
//
//                  This program is free software: you can redistribute it
//                  and/or modify it under the terms of the zlib/libpng License.
//                  See main.cpp for conditions of distribution and use.
//
// /////////////////////////////////////////////////////////////////////////////

#ifndef __ASSERIALIZABLE_H__
#define __ASSERIALIZABLE_H__

// Include files
#include "../../dependencies.h"

#ifdef __COMPILE_WITH_ANGELSCRIPT__

#include "../../core/Serializable.h"
#include "../ScriptHelper.h"


// ScriptedSerializable class
//! A class derived from Serializable, which makes it possible to interact with classes derived from
//! Serializable within AngelScript.
//! @note For internal use only!
class ScriptedSerializable : public Serializable
{
public:

    // Initialisation, deinitialisation and control...
    ScriptedSerializable(asIScriptObject *object);
    virtual ~ScriptedSerializable();

    // Serialization
    //! Serializes this object.
    //! @param attributes
    virtual bool onSerialization(SerializedAttributes *attributes);
    //! Deserializes this object.
    //! @param attributes
    virtual bool onDeserialization(SerializedAttributes *attributes);

private:

    // Private members
    asIScriptObject *mObject;
    asIScriptContext *mContext;

};

//! Binds the Serializable class to AngelScript.
extern void bindSerializable(asIScriptEngine *engine);

//! Binds the base behaviours and methods of the Serializable class to the given class in
//! AngelScript.
template<typename T>
void bindSerializableBase(asIScriptEngine *engine, const char *type)
{
    // Forward declaration.
    int r;
    std::string sType = type;

    // Set common behaviour.
    r = engine->RegisterObjectBehaviour(type, asBEHAVE_ADDREF, "void f()",
                                        asMETHOD(T, grab), asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectBehaviour(type, asBEHAVE_RELEASE, "void f()",
                                        asMETHOD(T, drop), asCALL_THISCALL); assert(r >= 0);

    r = engine->RegisterObjectBehaviour("Serializable", asBEHAVE_REF_CAST, std::string(sType + "@ f()").c_str(),
                                        asFUNCTION((asRefCast<Serializable,T>)), asCALL_CDECL_OBJLAST); assert( r >= 0 );
    r = engine->RegisterObjectBehaviour(type, asBEHAVE_IMPLICIT_REF_CAST, std::string("Serializable@ f()").c_str(),
                                        asFUNCTION((asRefCast<T,Serializable>)), asCALL_CDECL_OBJLAST); assert( r >= 0 );

    // Bind common class functions.
	r = engine->RegisterObjectMethod(type, "bool loadXML(const string &in)",
									asMETHODPR(T, loadXML, (const std::string&), bool), asCALL_THISCALL);
									assert(r >= 0);
    r = engine->RegisterObjectMethod(type, "bool saveXML(const string &in)",
                                    asMETHODPR(T, saveXML, (const std::string&), bool), asCALL_THISCALL);
									assert(r >= 0);
}

#endif // __COMPILE_WITH_ANGELSCRIPT__

#endif

